package TP6;

public class VectorEstado {

    private double reloj;
    private Evento evento;
    //  Esta referencia debería apuntar a la misma lista que la del expendedor... supongo.
    private double rndTipoGaseosa;
    private double rndSeVa;
    private double rndLlegadaCliente;
    private double rndFinAtencionCliente;
    private double finAtencion;
    private double rndGaseosaAlternativa;
    private double rndRomperEmpates;
    private double tiempoEntreLlegadasCliente;
    private double proximaLlegadaCliente;
    private Expendedor expendedor;
    private double rndLlegadaRepositor;
    private double tiempoEntreLlegadasRepositor;
    private double proximaLlegadaRepositor;
    private EstadoRepositor estadoRepositor;
    private double finReposicion;
    private int contadorPersonasAtendidas = 0;
    private int contadorPersonasNoConsiguieronGaseosaDeseada = 0;
    private int contadorPersonasNoConsiguieronGaseosaYseFueron = 0;
    private tipoGaseosa gaseosaAlternativa;
    private tipoGaseosa gaseosaElejida;
    public Evento eventoSiguiente;
    private boolean siSeVa;
    private double rndDiscoLleno = 1;
    private double porcentajeLlenadoDisco = 0;
    private double tiempoEntreLlenadoDisco = 0;

    public void setGaseosaAlternativa(tipoGaseosa gaseosaAlternativa) {
        this.gaseosaAlternativa = gaseosaAlternativa;
    }

    public void setGaseosaElegida(tipoGaseosa gaseosaElejida) {
        this.gaseosaElejida = gaseosaElejida;
    }

    public Expendedor getExpendedor() {
        return expendedor;
    }

    public VectorEstado(VectorEstado actual) {
        rndFinAtencionCliente = 1;
        rndGaseosaAlternativa = 1;
        rndLlegadaCliente = 1;
        rndLlegadaRepositor = 1;
        rndRomperEmpates = 1;
        rndSeVa = 1;
        rndTipoGaseosa = 1;
        rndDiscoLleno = 1;

        reloj = actual.getReloj();
        gaseosaAlternativa = actual.getGaseosaAlternativa();
        gaseosaElejida = actual.getGaseosaElegida();
        siSeVa = actual.getSiSeVa();


        porcentajeLlenadoDisco = actual.getPorcentajeDiscoLleno();
        tiempoEntreLlenadoDisco=actual.getProximoLlenadoDisco();

        finAtencion = actual.getFinAtencion();
        finReposicion = actual.getFinReposicion();
        proximaLlegadaCliente = actual.getProximaLlegadaCliente();
        proximaLlegadaRepositor = actual.getProximaLlegadaRepositor();
        estadoRepositor = actual.estadoRepositor;

        tiempoEntreLlegadasCliente = actual.tiempoEntreLlegadasCliente;
        tiempoEntreLlegadasRepositor = actual.tiempoEntreLlegadasRepositor;
        expendedor = new Expendedor(actual.getExpendedor());

        contadorPersonasNoConsiguieronGaseosaDeseada = actual.getContadorPersonasNoConsiguieronGaseosaDeseada();
        contadorPersonasNoConsiguieronGaseosaYseFueron = actual.getContadorPersonasNoConsiguieronGaseosaYseFueron();
        contadorPersonasAtendidas = actual.contadorPersonasAtendidas;
    }

    public void iniciarVector() {
        evento = Evento.INICIAL;
        this.evento.calcularProximaLlegada(this);


    }

    public VectorEstado(Expendedor expendedor) {
        this.expendedor = expendedor;
        evento = Evento.INICIAL;
        establecerEstadoRepositor();
        evento.calcularProximaLlegada(this);

    }

    public VectorEstado(int gaseosasA, int gaseosasB, int gaseosasC, int capacidad) {
        expendedor = new Expendedor(gaseosasA, gaseosasB, gaseosasC, capacidad);
    }

    public int getTamanoColaClientes() {
        return getExpendedor().getClientes().size();
    }

    public double getRndFinAtencionCliente() {
        return rndFinAtencionCliente;
    }

    public void setRndFinAtencionCliente() {
        this.rndFinAtencionCliente = Math.random();
    }

    public double getFinAtencion() {
        return finAtencion;
    }

    public void setFinAtencion(double finAtencion) {
        this.finAtencion = finAtencion;
    }

    public double getRndGaseosaAlternativa() {
        return rndGaseosaAlternativa;
    }

    public void setRndGaseosaAlternativa() {
        this.rndGaseosaAlternativa = Math.random();
        switch (gaseosaElejida) {
            case GaseosaA:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaB;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaC;
                }

                break;

            case GaseosaB:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaC;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaA;
                }
                break;

            case GaseosaC:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaA;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaB;
                }
                break;


            default:
                gaseosaAlternativa = tipoGaseosa.xxx;
        }
    }

    public double getRndRomperEmpates() {
        return rndRomperEmpates;
    }

    public void setRndRomperEmpates() {
        this.rndRomperEmpates = Math.random();
    }

    public double getTiempoEntreLlegadasCliente() {
        return tiempoEntreLlegadasCliente;
    }

    public void setTiempoEntreLlegadasCliente(double tiempoEntreLlegadasCliente) {
        this.tiempoEntreLlegadasCliente = tiempoEntreLlegadasCliente;
    }

    public double getProximaLlegadaCliente() {
        return proximaLlegadaCliente;
    }

    public void setProximaLlegadaCliente(double tiempoProxLLegada) {
        proximaLlegadaCliente = tiempoProxLLegada;
    }

    public double getTiempoEntreLlegadasRepositor() {
        return tiempoEntreLlegadasRepositor;
    }

    public void setTiempoEntreLlegadasRepositor(double tiempoEntreLlegadasRepositor) {
        this.tiempoEntreLlegadasRepositor = tiempoEntreLlegadasRepositor;
    }

    public double getProximaLlegadaRepositor() {
        return proximaLlegadaRepositor;
    }

    public void setProximaLlegadaRepositor(double proximaLlegadaRepositor) {
        this.proximaLlegadaRepositor = proximaLlegadaRepositor;
    }

    public EstadoRepositor getEstadoRepositor() {
        return estadoRepositor;
    }

    public void setEstadoRepositor(EstadoRepositor estadoRepositor) {
        this.estadoRepositor = estadoRepositor;
    }

    public double getFinReposicion() {
        return finReposicion;
    }

    public void setFinReposicion(double finReposicion) {
        this.finReposicion = finReposicion;
    }

    public int getContadorDeCambiosC() {
        return expendedor.getContDeCambiosC();
    }

    public int getContadorDeCambiosA() {
        return expendedor.getContDeCambiosA();
    }

    public int getContadorDeCambiosB() {
        return expendedor.getContDeCambiosB();
    }

    public int getContadorDeReposiciones() {
        return expendedor.getContReposiciones();
    }

    public int getContadorPersonasNoConsiguieronGaseosaDeseada() {
        return contadorPersonasNoConsiguieronGaseosaDeseada;
    }

    public void setContadorPersonasNoConsiguieronGaseosaDeseada(int contadorPersonasNoConsiguieronGaseosaDeseada) {
        this.contadorPersonasNoConsiguieronGaseosaDeseada = contadorPersonasNoConsiguieronGaseosaDeseada;
    }

    public int getContadorPersonasNoConsiguieronGaseosaYseFueron() {
        return contadorPersonasNoConsiguieronGaseosaYseFueron;
    }

    public void setContadorPersonasNoConsiguieronGaseosaYseFueron(int contadorPersonasNoConsiguieronGaseosaYseFueron) {
        this.contadorPersonasNoConsiguieronGaseosaYseFueron = contadorPersonasNoConsiguieronGaseosaYseFueron;
    }

    public double getReloj() {
        return reloj;
    }

    public void setReloj(double reloj) {
        this.reloj = reloj;
    }

    public Evento getEvento() {
        return evento;
    }

    public void setEvento(Evento evento) {
        this.evento = evento;
    }

    public double getRndTipoGaseosa() {
        return rndTipoGaseosa;
    }

    public void setRndTipoGaseosa() {
        this.rndTipoGaseosa = Math.random();
        if (rndTipoGaseosa < 0.55) {
            gaseosaElejida = tipoGaseosa.GaseosaA;


        }
        if (rndTipoGaseosa >= 0.55 && rndTipoGaseosa < 0.90) {
            gaseosaElejida = tipoGaseosa.GaseosaB;

        }
        if (rndTipoGaseosa >= 0.90) {
            gaseosaElejida = tipoGaseosa.GaseosaC;
        }
    }

    public double getRndSeVa() {
        return rndSeVa;
    }

    public void setRndSeVa() {
        this.rndSeVa = Math.random();
        if (rndSeVa > 0.5) {
            siSeVa = true;
        } else {
            siSeVa = false;
        }
    }

    public double getRndLlegadaCliente() {
        return rndLlegadaCliente;
    }

    public void setRndLlegadaCliente() {
        this.rndLlegadaCliente = Math.random();
    }

    public double getRndLlegadaRepositor() {
        return rndLlegadaRepositor;
    }

    public void setRndLlegadaRepositor() {
        this.rndLlegadaRepositor = Math.random();
    }

    public void setExpendedor(Expendedor ex) {
        expendedor = ex;
    }

    private void establecerEstadoRepositor() {
        if (expendedor.getEstado() == EstadoServidor.OCUPADO_POR_CLIENTE) {
            estadoRepositor = EstadoRepositor.ESPERANDO;
        } else if (expendedor.getEstado() == EstadoServidor.LIBRE) {
            estadoRepositor = EstadoRepositor.REPONIENDO;
        }
    }

    public tipoGaseosa getGaseosaElegida() {
        return gaseosaElejida;
    }

    public boolean getSiSeVa() {
        return siSeVa;
    }

    public tipoGaseosa getGaseosaAlternativa() {

        return gaseosaAlternativa;

    }

    public String getEmpateStock() {
        return " no implementado todavia el metodo";
    }

    public double getRelojEventoProximo() {
        // sumamos 2 tiempos de eventos para obligar la comparacion
        double min = this.getFinAtencion() + this.getFinReposicion() + this.getProximaLlegadaCliente() + this.getProximaLlegadaRepositor();

        if (this.getFinAtencion() < min && this.getFinAtencion() > this.getReloj()) {
            min = this.getFinAtencion();
            eventoSiguiente = Evento.FIN_ATENCION_CLIENTE;
        }
        if (this.getFinReposicion() < min && this.getFinReposicion() > this.getReloj()) {
            min = this.getFinReposicion();
            eventoSiguiente = Evento.FIN_REPOSICION;
        }
        if (this.getProximaLlegadaCliente() < min && this.getProximaLlegadaCliente() > this.getReloj()) {
            min = this.getProximaLlegadaCliente();
            eventoSiguiente = Evento.LLEGADA_CLIENTE;
        }
        if (this.getProximaLlegadaRepositor() < min && this.getProximaLlegadaRepositor() > this.getReloj()) {
            min = this.getProximaLlegadaRepositor();
            eventoSiguiente = Evento.LLEGADA_REPOSITOR;
        }

        if (this.getProximoLlenadoDisco() < min && this.getProximoLlenadoDisco() > this.getReloj()) {
            min = this.getProximoLlenadoDisco();
            eventoSiguiente = Evento.DISCO_LLENO;
        }
        return min;
    }

    public void calcularProximoEvento() {
        if (getReloj() == getProximaLlegadaCliente()) {
            evento = Evento.LLEGADA_CLIENTE;
        }
        if (getReloj() == getProximaLlegadaRepositor()) {
            evento = Evento.LLEGADA_REPOSITOR;
        }
        if (getReloj() == getFinAtencion()) {
            evento = Evento.FIN_ATENCION_CLIENTE;
        }
        if (getReloj() == getFinReposicion()) {
            evento = Evento.FIN_REPOSICION;
        }

        if (getReloj() == getProximoLlenadoDisco()) {
            evento = Evento.DISCO_LLENO;
        }

    }

    public void contarPersonaSinGaseosaDeseada() {
        contadorPersonasNoConsiguieronGaseosaDeseada++;
    }

    public void contarPersonasQueSeFueron() {
        contadorPersonasNoConsiguieronGaseosaYseFueron++;
    }

    public void contarPersonasAtendidas() {
        contadorPersonasAtendidas++;
    }

    public int getContadorPersonasAtendidas() {
        return contadorPersonasAtendidas;
    }

    public void setSiSeVa(boolean b) {
        siSeVa = true;
    }

    void setRndGaseosaAlternativa(double d) {
        rndGaseosaAlternativa = d;
        gaseosaAlternativa = null;
    }

    public void setRndDiscoLleno() {
        rndDiscoLleno = Math.random();
        if (rndDiscoLleno >= 0.50) {
            porcentajeLlenadoDisco = 1;
        }
        if (rndDiscoLleno < 0.50 && rndDiscoLleno >= 0.20) {
            porcentajeLlenadoDisco = 0.7;
        }
        if (rndDiscoLleno < 0.20) {
            porcentajeLlenadoDisco = 0.5;
        }
    }

    public double getRndDiscoLleno() {
        return rndDiscoLleno;
    }

    public void setProximoLlenadoDisco(double d) {
        this.tiempoEntreLlenadoDisco = d;
    }

    public double getProximoLlenadoDisco() {
        return tiempoEntreLlenadoDisco;
    }

    public double getPorcentajeDiscoLleno() {
        return porcentajeLlenadoDisco;
    }

    public enum tipoGaseosa {

        GaseosaA, GaseosaB, GaseosaC, xxx
    }
}
